package ray.create;

import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.internal.util.StringUtility;

import java.util.ArrayList;
import java.util.List;

/**
 * generate service class
 *
 * @author ray
 * @date 2016-03-17 10:34:45
 */
public class MybatisControllerPlugin extends PluginAdapter {

    private FullyQualifiedJavaType slf4jLogger;
    private FullyQualifiedJavaType slf4jLoggerFactory;
    private FullyQualifiedJavaType controllerType;
    private FullyQualifiedJavaType pojoType;
    private FullyQualifiedJavaType serviceType;

    private FullyQualifiedJavaType autowired;
    private FullyQualifiedJavaType controller;
    private FullyQualifiedJavaType requestMapping;
    private String controllerPack;
    private String servicePack;
    private String project;
    private String pojoUrl;


    /**
     * 是否添加注解
     */
    private boolean enableAnnotation = true;


    public MybatisControllerPlugin() {
        super();
        // default is slf4j
        slf4jLogger = new FullyQualifiedJavaType("org.slf4j.Logger");
        slf4jLoggerFactory = new FullyQualifiedJavaType("org.slf4j.LoggerFactory");

    }

    /**
     * 读取配置文件
     */
    @Override
    public boolean validate(List<String> warnings) {

        String enableAnnotation = properties.getProperty("enableAnnotation");


        if (StringUtility.stringHasValue(enableAnnotation)) {
            this.enableAnnotation = StringUtility.isTrue(enableAnnotation);
        }


        this.servicePack = properties.getProperty("servicePackage");
        this.controllerPack = properties.getProperty("targetPackage");
        this.project = properties.getProperty("targetProject");
        this.pojoUrl = context.getJavaModelGeneratorConfiguration().getTargetPackage();

        if (this.enableAnnotation) {
            autowired = new FullyQualifiedJavaType("javax.annotation.Resource");
            //autowired = new FullyQualifiedJavaType("org.springframework.beans.factory.annotation.Autowired");
            controller = new FullyQualifiedJavaType("org.springframework.stereotype.Controller");
            requestMapping = new FullyQualifiedJavaType("org.springframework.web.bind.annotation.RequestMapping");

        }
        return true;
    }

    /**
     *
     */
    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
        List<GeneratedJavaFile> files = new ArrayList<GeneratedJavaFile>();

        String table = introspectedTable.getBaseRecordType();
        String tableName = table.replaceAll(this.pojoUrl + ".", "");

        controllerType = new FullyQualifiedJavaType(controllerPack + "." + tableName + "Controller");

        serviceType = new FullyQualifiedJavaType(tableName + "Service");

        pojoType = new FullyQualifiedJavaType(pojoUrl + "." + tableName);

        TopLevelClass topLevelClass = new TopLevelClass(controllerType);

        // 导入必须的类
        addImport(topLevelClass, tableName);
        // controller
        addController(topLevelClass, introspectedTable, tableName, files);
        addLogger(topLevelClass);

        return files;
    }


    /**
     * add implements class
     *
     * @param introspectedTable introspectedTable
     * @param tableName         tableName
     * @param files             files
     */
    protected void addController(TopLevelClass topLevelClass, IntrospectedTable introspectedTable, String tableName, List<GeneratedJavaFile> files) {

        topLevelClass.addJavaDocLine("/**");
        topLevelClass.addJavaDocLine(" *");
        topLevelClass.addJavaDocLine(" *@author create by Generator ");
        topLevelClass.addJavaDocLine(" **/");

        topLevelClass.setVisibility(JavaVisibility.PUBLIC);
        topLevelClass.setSuperClass("WebController");
        if (enableAnnotation) {
            topLevelClass.addAnnotation("@Controller");
            topLevelClass.addImportedType(controller);
            topLevelClass.addAnnotation("@RequestMapping(\"" + Utils.toLowerCase(controllerType.getShortName()) + "\")");
            topLevelClass.addImportedType(requestMapping);
        }
        addField(topLevelClass, tableName);


        //此外报错[已修2016-03-22，增加:",context.getJavaFormatter()"]
        GeneratedJavaFile file = new GeneratedJavaFile(topLevelClass, project, context.getJavaFormatter());
        files.add(file);
    }


    /**
     * 添加字段
     *
     * @param topLevelClass topLevelClass
     */
    protected void addField(TopLevelClass topLevelClass, String tableName) {
        Field field = new Field();
        field.setName(Utils.toLowerCase(tableName + "Service"));
        topLevelClass.addImportedType(serviceType);
        field.setType(serviceType);
        field.setVisibility(JavaVisibility.PRIVATE);
        if (enableAnnotation) {
            field.addAnnotation("@Resource");
        }
        topLevelClass.addField(field);
    }


    protected void addComment(JavaElement field, String comment) {
        StringBuilder sb = new StringBuilder();
        field.addJavaDocLine("/**");
        sb.append(" * ");
        comment = comment.replaceAll("\n", "<br>\n\t * ");
        sb.append(comment);
        field.addJavaDocLine(sb.toString());
        field.addJavaDocLine(" */");
    }


    /**
     * import must class
     */
    private void addImport(TopLevelClass topLevelClass, String tableName) {
        topLevelClass.addImportedType(new FullyQualifiedJavaType("com.zjhc.flyhong.common.function.operator.LoginUser"));
        topLevelClass.addImportedType(new FullyQualifiedJavaType("com.zjhc.flyhong.common.web.Result"));
        topLevelClass.addImportedType(new FullyQualifiedJavaType("com.zjhc.flyhong.common.function.operator.PageDTO"));
        topLevelClass.addImportedType(new FullyQualifiedJavaType("com.zjhc.web.controller.WebController"));
        topLevelClass.addImportedType(pojoType);
        topLevelClass.addImportedType(slf4jLogger);
        topLevelClass.addImportedType(slf4jLoggerFactory);
        topLevelClass.addImportedType(servicePack + "." + tableName + "Service");
        if (enableAnnotation) {
            topLevelClass.addImportedType(controller);
            topLevelClass.addImportedType(autowired);
            topLevelClass.addImportedType(requestMapping);
        }
    }

    /**
     * import logger
     */
    private void addLogger(TopLevelClass topLevelClass) {
        Field field = new Field();
        field.setFinal(true);
        field.setInitializationString("LoggerFactory.getLogger(" + topLevelClass.getType().getShortName() + ".class)"); // set value
        field.setName("logger"); // set var name
        field.setStatic(true);
        field.setType(new FullyQualifiedJavaType("Logger")); // type
        field.setVisibility(JavaVisibility.PRIVATE);
        topLevelClass.addField(field);
    }

}
